package ez

import (
	"context"
	"strings"
	"sync"
)

type Handler func(v interface{}, ctx context.Context)

type BusToOne map[string]Handler
type BusToMany map[string][]Handler

var busToOne map[string]Handler
var busToMany map[string][]Handler

func init() {
	busToOne = make(map[string]Handler)
	busToMany = make(map[string][]Handler)
}

// Listen 订阅事件，单人订阅
func Listen(name string, handler Handler) {
	busToOne[name] = handler
}

func DispatchToOne(name string, data interface{}, ctx context.Context) {
	handler, ok := busToOne[name]
	if ok {
		handler(data, ctx)
	}
}

// Subscribe 订阅事件，多个人可以同时订阅同一个事件
func Subscribe(name string, handler Handler) {
	eventNames := strings.Split(name, " ")
	for _, eventName := range eventNames {
		busToMany[eventName] = append(busToMany[eventName], handler)
	}
}

// DispatchToManySync 同步事件分发，必须等待上一个完成后才能执行下一个
func DispatchToManySync(name string, data interface{}, ctx context.Context) {
	handlers, ok := busToMany[name]
	if ok {
		for _, handler := range handlers {
			handler(data, ctx)
		}
	}
}

// DispatchToMany 异步事件分发
func DispatchToMany(name string, data interface{}, ctx context.Context) {
	handlers, ok := busToMany[name]
	if ok {
		var wg sync.WaitGroup
		wg.Add(len(handlers))
		for _, handler := range handlers {
			go func(handler2 Handler) {
				handler2(data, ctx)
				wg.Done()
			}(handler)
		}
		wg.Wait()
	}
}
